package com.tgu.home_action.service.impl;

import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.facebody.model.v20191230.SearchFaceResponse;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tgu.home_action.dao.CaseMapper;
import com.tgu.home_action.dao.FaceMapper;
import com.tgu.home_action.dao.OldManMapper;
import com.tgu.home_action.dao.VolunteerCaseMapper;
import com.tgu.home_action.pojo.*;
import com.tgu.home_action.pojo.state.RabbitMq;
import com.tgu.home_action.pojo.state.RedisHeader;
import com.tgu.home_action.pojo.state.ResponseState;
import com.tgu.home_action.service.CaseService;
import com.tgu.home_action.service.utils.AliYunService;
import com.tgu.home_action.service.utils.IMService;
import com.tgu.home_action.service.utils.StringService;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.geo.Point;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.validation.constraints.NotNull;
import java.sql.Timestamp;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Validated
@Service
public class CaseServiceImpl implements CaseService {
    @Autowired
    private IMService imService;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private VolunteerCaseMapper volunteerCaseMapper;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private OldManMapper oldManMapper;
    @Autowired
    private CaseMapper caseMapper;
    @Autowired
    private AliYunService aliYunService;
    @Autowired
    private SimpMessagingTemplate simpMessagingTemplate;
    @Autowired
    private FaceMapper faceMapper;

    /**
     * 发布案件
     */
    @Override
    @Transactional
    public ResponseData<Object> publishCase(Case newCase, Family family) {
        List<Case> oldCase = caseMapper.getByOldManId(newCase.getOldManId());
        if (oldCase != null) {
            if (oldCase.size() > 0) {
                return new ResponseData<>(ResponseState.OLD_MAN_CASE_IS_ING.getMessage(), ResponseState.OLD_MAN_CASE_IS_ING.getValue());
            }
        }
        //判断该老人信息是否为当前家属的
        OldMan oldMan = oldManMapper.getById(newCase.getOldManId());
        System.out.println(oldMan.getId());
        System.out.println(family.getId());
        if (oldMan != null) {
            if (!oldMan.getFamilyId().equals(family.getId())) {
                return new ResponseData<>(ResponseState.OLD_MAN_NOT_EXIST.getMessage(), ResponseState.OLD_MAN_NOT_EXIST.getValue());
            }
        } else {
            return new ResponseData<>(ResponseState.OLD_MAN_NOT_EXIST.getMessage(), ResponseState.OLD_MAN_NOT_EXIST.getValue());
        }
        //设置案件开始时间
        newCase.setStartTime(new Timestamp(new Date().getTime()));
        newCase.setFamilyId(family.getId());
        newCase.setGis(StringService.getGis(newCase.getLongitude(), newCase.getLatitude()));
        newCase.setId(90);
        System.out.println("CaseId:"+newCase.getId());
        caseMapper.insertCase(newCase);
        newCase.setOldMan(oldMan);
        stringRedisTemplate.opsForValue().set(RedisHeader.CASE_TIME.getHeader() + "__" + newCase.getId(), String.valueOf(new Date().getTime()), 7, TimeUnit.DAYS);
        rabbitTemplate.convertAndSend(RabbitMq.CASE_EXCHANGE.getValue(), RabbitMq.CASE_SEND_MESSAGE.getValue(), newCase);
        rabbitTemplate.convertAndSend(RabbitMq.CASE_EXCHANGE.getValue(), RabbitMq.CASE_SEND.getValue(), newCase);
        rabbitTemplate.convertAndSend(RabbitMq.CASE_EXCHANGE.getValue(), RabbitMq.CASE_CREATE_GROUP.getValue(), newCase);
        return new ResponseData<>(ResponseState.SUCCESS.getMessage(), ResponseState.SUCCESS.getValue());
    }

    /**
     * 修改案件
     */
    @Override
    @Transactional
    public ResponseData<Object> updateCase(Case nowCase, Family family) {
        OldMan oldMan = oldManMapper.getById(nowCase.getOldManId());
        if (nowCase.getLatitude() != null) {
            if (nowCase.getLongitude() == null) {
                return new ResponseData<>("经纬度必须同时提供", ResponseState.PARAM_IS_ERROR.getValue());
            }
            nowCase.setGis(StringService.getGis(nowCase.getLongitude(), nowCase.getLatitude()));
        }
        if (nowCase.getOldManId() != null) {
            //判断该老人信息是否为当前家属的
            if (oldMan != null) {
                if (!oldMan.getFamilyId().equals(family.getId())) {
                    return new ResponseData<>(ResponseState.OLD_MAN_NOT_EXIST.getMessage(), ResponseState.OLD_MAN_NOT_EXIST.getValue());
                }
            } else {
                return new ResponseData<>(ResponseState.OLD_MAN_NOT_EXIST.getMessage(), ResponseState.OLD_MAN_NOT_EXIST.getValue());
            }
        }
        nowCase.setFamilyId(family.getId());
        System.out.println(family.getId());
        Boolean isSuccess = caseMapper.updateCase(nowCase);
        if (isSuccess) {
            nowCase = caseMapper.getById(nowCase.getId());
            nowCase.setOldMan(oldMan);
            rabbitTemplate.convertAndSend(RabbitMq.CASE_EXCHANGE.getValue(), RabbitMq.CASE_INFORMATION_UPDATE.getValue(), nowCase);
            return new ResponseData<>(ResponseState.SUCCESS.getMessage(), ResponseState.SUCCESS.getValue());
        } else {
            return new ResponseData<>(ResponseState.CASE_NOT_EXIST.getMessage(), ResponseState.CASE_NOT_EXIST.getValue());
        }
    }

    /**
     * 结束案件
     */
    @Override
    public ResponseData<Object> endCase(Integer caseId, Short state, Family family) {
        if (state != 2 && state != 4) {
            return new ResponseData<>("state只能是2或4", ResponseState.PARAM_IS_ERROR.getValue());
        }
        Case nowCase = caseMapper.getById(caseId);
        System.out.println(nowCase.toString());
        if (nowCase == null) {
            return new ResponseData<>(ResponseState.CASE_NOT_EXIST.getMessage(), ResponseState.CASE_NOT_EXIST.getValue());
        }
        if (nowCase.getState() != 1 && nowCase.getState() != 3) {
            return new ResponseData<>(ResponseState.OPERATION_HAI_FINISH.getMessage(), ResponseState.OPERATION_HAI_FINISH.getValue());
        }
        if (!family.getId().equals(nowCase.getFamilyId())) {
            return new ResponseData<>(ResponseState.WITHOUT_PERMISSION.getMessage(), ResponseState.WITHOUT_PERMISSION.getValue());
        }
        nowCase.setState(state);
        Boolean isSuccess = caseMapper.changeCaseState(caseId, state);
        //设置完成时间
        nowCase.setEndTime(new Timestamp(new Date().getTime()));
        caseMapper.setEndTime(nowCase);
        if (isSuccess) {
            System.out.println("完成state修改");
            rabbitTemplate.convertAndSend(RabbitMq.CASE_EXCHANGE.getValue(), RabbitMq.CASE_FINISH.getValue(), nowCase);
//            rabbitTemplate.convertAndSend(RabbitMq.CASE_EXCHANGE.getValue(),RabbitMq.CASE_END.getValue(),nowCase);
            return new ResponseData<>(ResponseState.SUCCESS.getMessage(), ResponseState.SUCCESS.getValue());
        } else {
            return new ResponseData<>(ResponseState.CASE_NOT_EXIST.getMessage(), ResponseState.CASE_NOT_EXIST.getValue());
        }
    }

    /**
     * 查询案件
     */
    @Override
    public ResponseData<List<Case>> getCases(Case caseInformation) {
        List<Case> cases = caseMapper.getCases(caseInformation);
        return new ResponseData<>(ResponseState.SUCCESS.getMessage(), ResponseState.SUCCESS.getValue(), cases);
    }

    /**
     * 查询案件数量
     */
    @Override
    public ResponseData<Integer> getCaseNumber() {
        int number = caseMapper.getCaseNumber();
        return new ResponseData<>(ResponseState.SUCCESS.getMessage(), ResponseState.SUCCESS.getValue(), number);
    }

    /**
     * 查询正在进行的案件
     */
    @Override
    public ResponseData<List<Case>> getIngCase(Double longitude, Double latitude, Integer timeDiff, Integer distance, Volunteer volunteer) {
        Timestamp startTime = null;
        if (timeDiff != null) {
            startTime = new Timestamp(new Date().getTime() - timeDiff * 3600 * 1000);
        }
        String gis = StringService.getGis(longitude, latitude);
        System.out.println(gis);
        List<Case> cases = caseMapper.getIngCase(startTime, distance, gis);
        return new ResponseData<>(ResponseState.SUCCESS.getMessage(), ResponseState.SUCCESS.getValue(), cases);
    }

    /**
     * 接受/拒绝/退出任务
     */
    @Override
    public ResponseData<Object> responseCase(VolunteerCase volunteerCase, Volunteer volunteer) {
        Case thisCase = caseMapper.getById(volunteerCase.getCaseId());
        if (thisCase == null) {
            return new ResponseData<>(ResponseState.CASE_NOT_EXIST.getMessage(), ResponseState.CASE_NOT_EXIST.getValue());
        }
        volunteerCase.setVolunteerId(volunteer.getId());
        VolunteerCase oldVolunteerCase = volunteerCaseMapper.getVolunteerCase(volunteerCase);
        //已有记录
        if (oldVolunteerCase != null) {
            //已参与退出
            if (volunteerCase.getState() == 3) {
                //判断是否已参与
                if (oldVolunteerCase.getState() != 1) {
                    return new ResponseData<>("当前未在该任务中,state只能是1", ResponseState.PARAM_IS_ERROR.getValue());
                }
                // 已经在该任务中，退出
                volunteerCaseMapper.updateState(volunteerCase);
                rabbitTemplate.convertAndSend(RabbitMq.VOLUNTEER_OUT.getValue(), volunteerCase);
                return new ResponseData<>(ResponseState.SUCCESS.getMessage(), ResponseState.SUCCESS.getValue());
            }
            //已有案件记录参与案件
            else if (volunteerCase.getState() == 1) {
                //判断是否未参与
                if (oldVolunteerCase.getState() == 1) {
                    return new ResponseData<>("此时正在参与案件，state只能是3", ResponseState.PARAM_IS_ERROR.getValue());
                }
                // 已经推出，重新参与
                volunteerCaseMapper.updateState(volunteerCase);
                rabbitTemplate.convertAndSend(RabbitMq.VOLUNTEER_IN.getValue(), volunteerCase);
                return new ResponseData<>(ResponseState.SUCCESS.getMessage(), ResponseState.SUCCESS.getValue());
            } else {
                return new ResponseData<>("已有案件记录，state只能是1或3", ResponseState.PARAM_IS_ERROR.getValue());
            }
        }
        //没有记录
        //接受
        volunteerCase.setCreateAt(new Timestamp(new Date().getTime()));
        if (volunteerCase.getState() == 1) {
            volunteerCaseMapper.insertVolunteerCase(volunteerCase);
            rabbitTemplate.convertAndSend(RabbitMq.VOLUNTEER_IN.getValue(), volunteerCase);
            return new ResponseData<>("接受任务成功", ResponseState.SUCCESS.getValue());
            //拒绝任务
        } else if (volunteerCase.getState() == 2) {
            volunteerCase.setEquipment(null);
            volunteerCase.setTraffic(null);
            volunteerCaseMapper.insertVolunteerCase(volunteerCase);
            return new ResponseData<>("拒绝任务成功", ResponseState.SUCCESS.getValue());
        } else {
            return new ResponseData<>("没有案件记录，state只能是1或2", ResponseState.PARAM_IS_ERROR.getValue());
        }
    }

    /**
     * 获取志愿者参与过的所有案件
     */
    @Override
    public ResponseData<List<Case>> getVolunteerCases(Integer volunteerId) {
        List<Case> cases = caseMapper.getVolunteerCases(volunteerId);
        return new ResponseData<>(ResponseState.SUCCESS.getMessage(), ResponseState.SUCCESS.getValue(), cases);
    }

    /**
     * 查询志愿者正在参与的案件
     */
    @Override
    public ResponseData<List<Case>> getVolunteerIngCases(Integer volunteerId) {
        List<Case> cases = caseMapper.getVolunteerIngCases(volunteerId);
        return new ResponseData<>(ResponseState.SUCCESS.getMessage(), ResponseState.SUCCESS.getValue(), cases);
    }

    /**
     * 志愿者查询本人正在参与的案件
     */
    @Override
    public ResponseData<List<Case>> getMyIngCases(Volunteer volunteer) {
        List<Case> cases = caseMapper.getMyIngCases(volunteer.getId());
        return new ResponseData<>(ResponseState.SUCCESS.getMessage(), ResponseState.SUCCESS.getValue(), cases);
    }

    /**
     * 获取正在进行但未参与的案件
     */
    @Override
    public ResponseData<List<Case>> getNewCases(Volunteer volunteer) {
        List<Case> cases = caseMapper.getNewCases(volunteer.getId());
        return new ResponseData<>(ResponseState.SUCCESS.getMessage(), ResponseState.SUCCESS.getValue(), cases);
    }

    /**
     * 获取案件参与的志愿者
     */
    @Override
    public ResponseData<List<Volunteer>> getVolunteers(Integer caseId) {
        List<Volunteer> volunteers = volunteerCaseMapper.getVolunteerByCaseId(caseId);
        for (Volunteer volunteer :
                volunteers) {
            List<Point> points = stringRedisTemplate.opsForGeo().position(RedisHeader.VOLUNTEER_PLACE.getHeader(), String.valueOf(volunteer.getId()));
            System.out.println(points.size());
            if (points == null) {
                volunteer.setOnline((short) 2);
                continue;
            }
            Point point = points.get(0);
            if (point == null) {
                volunteer.setOnline((short) 2);
                continue;
            }
            volunteer.setLongitude(point.getX());
            volunteer.setLatitude(point.getY());
            Boolean isMember = stringRedisTemplate.opsForSet().isMember(RedisHeader.VOLUNTEER_ONLINE.getHeader(), String.valueOf(volunteer.getId()));
            if (isMember == null) {
                isMember = false;
            }
            if (isMember) {
                volunteer.setOnline((short) 1);
            } else {
                volunteer.setOnline((short) 2);
            }

        }
        return new ResponseData<>(ResponseState.SUCCESS.getMessage(), ResponseState.SUCCESS.getValue(), volunteers);
    }


    /**
     * 查询家属的所有案件
     */
    @Override
    public ResponseData<List<Case>> getFamilyAllCase(Family family) {
        List<Case> cases = caseMapper.getByFamilyId(family.getId());
        return new ResponseData<>(ResponseState.SUCCESS.getMessage(), ResponseState.SUCCESS.getValue(), cases);
    }

    /**
     * 查询家属正在进行的案件
     */
    @Override
    public ResponseData<List<Case>> getFamilyIngCase(Family family) {
        List<Case> cases = caseMapper.getIngByFamilyId(family.getId());
        return new ResponseData<>(ResponseState.SUCCESS.getMessage(), ResponseState.SUCCESS.getValue(), cases);
    }

    /**
     * 通过id进行模糊搜索
     */
    @Override
    public ResponseData<List<Case>> getCaseByLikeId(String id) {
//        QueryWrapper<Case> caseQueryWrapper=new QueryWrapper<>();
//        caseQueryWrapper.like("id",id);
//        List<Case> cases=caseMapper.selectList(caseQueryWrapper);
        List<Case> cases=caseMapper.getCaseByLikeId(id);
        return new ResponseData<>(ResponseState.SUCCESS.getMessage(),ResponseState.SUCCESS.getValue(),cases);
    }

}
